/*

Routine Seriali hardware per PIC

*/

#include "rs232HW.h"

void hw_serial_setup(void)
     {
     /* relates crystal freq to baud rate - see above and PIC16F87x data sheet under 'USART async. modes'

     BRGH=1, Fosc=3.6864MHz		BRGH=1, Fosc=4MHz      		BRGH=1, Fosc=8MHz    BRGH=1, Fosc=16MHz
     ----------------------	  	-----------------      	       -----------------    ------------------
     Baud		SPBRG           Baud		SPBRG          Baud	SPBRG         Baud    SPBRG
     1200		191             1200		207.3          1200	415.7         9600    103
     2400		95              2400		103.2          2400	207.3         19200   51
     4800		47              4800		51.1           4800	103.2         38400   25
     9600		23              9600		25.0           9600	51.1          57600   16
     19200		11              19200		12.0           19200	25.0        	      115200  8
     38400		5               38400		5.5            38400	12.0
     57600		3               57600		3.3            57600	7.7
     115200		1               115200	1.2            	       115200	3.3
     */

     /*
     * Comms setup:
     */

     #define PIC_CLK=3686400
     #define BAUD 19200
     #define HIGH_SPEED 1

     //SPBRG=191;					//1200 BAUD a 3686400Hz
     //SPBRG=25;					//9600 BAUD a 4 MHz
     SPBRG=207;					//1200 BAUD a 4 MHz
     //SPBRG=12;						//19200 BAUD a 4 MHz
     BRGH=HIGH_SPEED;			//data rate for sending
     SYNC=0;						//asynchronous
     SPEN=1;						//enable serial port pins
     CREN=1;						//enable reception
     SREN=0;						//no effect
     TXIE=0;						//disable tx interrupts
     RCIE=0;						//disable rx interrupts
     TX9=0;							//8-bit transmission
     RX9=0;							//8-bit reception
     TXEN=0;						//reset transmitter
     TXEN=1;						//enable the transmitter
     }


//writes a character to the serial port
void hw_putch(unsigned char c)
{
     while(!TXIF)			/*set when register is empty*/
     {
     hw_clear_usart_errors();
     CLRWDT();
     }
     TXREG=c;
     DelayUs(60);
}

//gets a character from the serial port without timeout
unsigned char hw_getch(void)
{
	while(!RCIF)
	{
	CLRWDT();
	hw_clear_usart_errors();
	}
	return RCREG;
}



void hw_clear_usart_errors(void)
{
unsigned char dummy;

if (OERR)													\
{																	\
	TXEN=0;													\
	TXEN=1;													\
	CREN=0;													\
	CREN=1;													\
}																	\
if (FERR)													\
{																	\
	dummy=RCREG;										\
	TXEN=0;													\
	TXEN=1;													\
}

}



/*
writes a character to the serial port in hex
if serial lines are disconnected, there are no errors
*/

void hw_putchhex(unsigned char c)
{
	unsigned char temp;

	// transmits in hex

	temp=c;

	c=(c >> 4);
	if (c<10) c+=48; else c+=55;
	hw_putch(c);

	c=temp;

	c=(c & 0x0F);
	if (c<10) c+=48; else c+=55;
	hw_putch(c);
}

void hw_putinthex(unsigned int c)
{
	#define ramuint(x)						(*((unsigned int *) (x)))
	#define ramuint_hibyte(x)			(*(((unsigned char *)&x)+1))
	#define ramuint_lobyte(x)			(*(((unsigned char *)&x)+0))
	#define ramuchar(x)						(*((unsigned char *) (x)))

	hw_putchhex(ramuint_hibyte(c));
	hw_putchhex(ramuint_lobyte(c));

	#undef ramuint(x)
	#undef ramuint_hibyte(x)
	#undef ramuint_lobyte(x)
	#undef ramuchar(x)
}

/*
writes a character to the serial port in decimal
if serial lines are disconnected, there are no errors
*/
void hw_putchdec(unsigned char c)
{
	unsigned char temp;

	temp=c;
	//hundreds
	if ((c/100)>0) hw_putch((c/100)+'0');
	c-=(c/100)*100;

	//tens
	if (((temp/10)>0) || ((temp/100)>0)) hw_putch((c/10)+'0');
	c-=(c/10)*10;

	//ones
	hw_putch((c/1)+'0');
}

void hw_putintdec(unsigned int i)
{
	unsigned int temp;

	temp=i;

  	//Decine di migliaia
	if (((i/10000)>0)|| (temp/100000)>0) hw_putch((i/10000)+'0');
	i-=(i/10000)*10000;

 	//Migliaia
	if (((i/1000)>0) || (temp/10000)>0)hw_putch((i/1000)+'0');
	i-=(i/1000)*1000;

	//Centinaia
	if (((i/100)>0) || (temp/1000)>0) hw_putch((i/100)+'0');
	i-=(i/100)*100;

	//Decine
	if (((temp/10)>0) || (temp/100)>0) hw_putch((i/10)+'0');
	i-=(i/10)*10;

	//unita
	hw_putch((i/1)+'0');
}

void hw_putst(register const char *str)
{
	while((*str)!=0)
	{
	hw_putch(*str);
        if (*str==13) hw_putch(10);
        if (*str==10) hw_putch(13);
	str++;
	}
}

void hw_put_CRLF(void)
{
	hw_putch(0x0D);
	hw_putch(0x0A);
}
